package com.aron;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @version v1.0
 * @ProjectName: studycoding
 * @ClassName: TankFrame
 * @Description: TODO(坦克画布界面)
 * @Author: Leo
 * @Date: 2020/5/31 17:17
 */
public class TankFrame extends Frame {

    public static final int GAME_W = 800, GAME_H = 600;
    //单例模式控制坦克画布界面只存在一个
    private static TankFrame instance = new TankFrame();

    Image offScreenImage = null;
    //玩家
    private PlayerTank myTank;
    //敌人
    private List<EnemyTank> enemyTanks;
    //导弹数据
    private List<Missile> missiles;

    //爆炸效果
    private List<TankBlast> tankBlasts;
    //击杀坦克数量
    private int killTankCount=0;

    /**
     * 初始化窗口
     */
    private TankFrame() {
        this.setTitle("坦克世界");
        this.setLocation(400, 100);
        this.setSize(GAME_W, GAME_H);

        initGameObj();
        //设计模式：观察者模式
        this.addKeyListener(new TankKeyListener());
    }


    private void initGameObj() {
        myTank = new PlayerTank(350, 500, Dir.UP, TankGroup.PLAYER);
        enemyTanks = new ArrayList<EnemyTank>();

        for (int i = 0; i < 10; i++) {
            enemyTanks.add(new EnemyTank(150 + 50 * i, 100, Dir.DOWN, TankGroup.ENEMY));
        }
        missiles = new ArrayList<Missile>();
        tankBlasts=new ArrayList<TankBlast>();
    }

    public static TankFrame getInstance() {
        if (instance == null) {
            instance = new TankFrame();
        }
        return instance;
    }


    //添加画布中导弹
    public void addMissile(Missile missile) {
        this.missiles.add(missile);
    }

    public  void addBlast(TankBlast tankBlast){
        this.tankBlasts.add(tankBlast);
    }
    /**
     * 重写Frame中的paint方法
     *
     * @param g
     */
    private Random r=new Random();
    @Override
    public void paint(Graphics g) {
        g.setColor(Color.WHITE);
        g.drawString("子弹数量：" + missiles.size(), 10, 50);
        g.drawString("敌方数量：" + enemyTanks.size(), 10, 70);
        g.drawString("击杀数量：" + killTankCount, 10, 90);
        myTank.paint(g);
        //判断敌方坦克数量少于一定值时，字段加入随机数量的地方坦克。
        if(enemyTanks.size()<3){
            for (int i = 0; i <  r.nextInt(10); i++) {
                enemyTanks.add(new EnemyTank(100 + (80 * i), 100, Dir.DOWN, TankGroup.ENEMY));
            }
        }
        for (int i = 0; i < enemyTanks.size(); i++) {
            if(enemyTanks.get(i).isLive()){
                enemyTanks.get(i).paint(g);
            }else {
                enemyTanks.remove(i);
                killTankCount++;
            }

        }
        //循环爆炸效果
        for (int i = 0; i <  tankBlasts.size(); i++) {
            if(tankBlasts.get(i).isLive()){
                tankBlasts.get(i).print(g);
            }else{
                tankBlasts.remove(i);
            }
        }

        for (int i = 0; i < missiles.size(); i++) {
            //当导弹和敌方坦克撞上时
            if (missiles.get(i).getGroup() == TankGroup.PLAYER) {
                for (int j = 0; j < enemyTanks.size(); j++) {
                    missiles.get(i).blastWithTank(enemyTanks.get(j));
                }
            }
            //当导弹和玩家坦克撞上时
            if (missiles.get(i).getGroup() == TankGroup.ENEMY) {
                //missiles.get(i).blastWithTank(myTank);
            }

            if (missiles.get(i).isLive()) {
                missiles.get(i).print(g);
            } else {
                missiles.remove(i);
            }

        }
    }

    /**
     * 重新update，因为repaint调用的是update方法。
     * 以下是用于处理加载坦克闪烁问题
     *
     * @param g
     */
    @Override
    public void update(Graphics g) {
        if (offScreenImage == null) {
            offScreenImage = this.createImage(GAME_W, GAME_H);
        }
        Graphics graphics = offScreenImage.getGraphics();
        //Color color=graphics.getColor();
        graphics.setColor(Color.BLACK);
        graphics.fillRect(0, 0, GAME_W, GAME_H);
        //graphics.setColor(color);
        paint(graphics);
        g.drawImage(offScreenImage, 0, 0, null);
    }

    /**
     * 为什么使用内部类
     * 不需要让别的类访问键盘监听类
     * 设计原则：高内聚 低耦合
     * 为什么不使用方法的内部类（局部内部类)
     * 使用implements实现一个类则必须实现接口的所有方法
     * 使用extends继承
     */
    private class TankKeyListener extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            myTank.keyPressed(e);
        }

        @Override
        public void keyReleased(KeyEvent e) {
            myTank.keyReleased(e);
        }
    }


}
